
//Copyright 1997-2009 Syrinx Development, Inc.
//This file is part of the Syrinx Web Application Framework (SWAF).
// == BEGIN LICENSE ==
//
// Licensed under the terms of any of the following licenses at your
// choice:
//
//  - GNU General Public License Version 3 or later (the "GPL")
//    http://www.gnu.org/licenses/gpl.html
//
//  - GNU Lesser General Public License Version 3 or later (the "LGPL")
//    http://www.gnu.org/licenses/lgpl.html
//
//  - Mozilla Public License Version 1.1 or later (the "MPL")
//    http://www.mozilla.org/MPL/MPL-1.1.html
//
// == END LICENSE ==
using System;
using System.Collections;
using System.Xml;

using Swaf;
using Swaf.Container;

namespace Swaf.Call
{
	/// <summary>
	/// Uses IApplication.appData and IApplication.sessionData as root elements in a 
	/// INameAddress data model tree.
	/// </summary>
	/// <remarks></remarks>
	public class DataModelCall : BaseCall
	{
		protected string[] m_paramNames;

		public DataModelCall(string id, XmlElement initInfo)
			:base(id, initInfo)
		{
			if(initInfo.HasAttribute("paramNames"))
			{
				string paramNames = initInfo.GetAttribute("paramNames");
				if(paramNames.Length > 0)
				{
					m_paramNames = paramNames.Split(',');
					for(int pos = 0; pos < m_paramNames.Length; ++pos)
						m_paramNames[pos] = m_paramNames[pos].Trim();
				}
				else
					m_paramNames = new string[0];
			}
		}

		public override object call(params object[] p)
		{
			object results = null;

			object[] actualParams = calcCallParams(p);
			object lastParamObject=null;
			object[] lastParamArray=null;
			object actual = null;
	
			if(actualParams != null && actualParams.Length == 3 && actualParams[0] is IApplication) 
				
			{
				if ((actualParams[2] is INameAddressSupport) || (actualParams[2] == null ))
				{
					lastParamObject = actualParams[2];
				}
				else if (actualParams[2] is object[] )
				{
					//This call is probably comming from the rulemanager.  Use the 3rd param as the actual params
					lastParamArray = (object[])actualParams[2];
				}
			}
			else
			{
				lastParamArray=actualParams;
			}
			if((m_paramNames != null) && (lastParamArray != null))
			{
				int pos = 0;
				IMap a = new FlexiMap();
				foreach(string name in m_paramNames)
					if(lastParamArray.Length > pos)
						a[name] = lastParamArray[pos++];
				actual = a;
			}
			else if (lastParamArray != null)
			{
				actual = lastParamArray;
			}
			else
			{
				actual = lastParamObject; 
			}

			if(String.Compare(m_className, "application", true) == 0)
				results = Application.currentApp.appData.get(m_methodName, actual);
			else if(String.Compare(m_className, "session", true) == 0)
			{
				IApplication app = Application.currentApp;
				if(p != null && p.Length > 0 && p[0] is IApplication)
					app = (IApplication)p[0];
				results = app.sessionData.get(m_methodName, actual);
			}
			else
				throw new CallException(String.Format("Unknown Namespace root: {0}", m_className));

			return results;
		}

	}
}
